package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.cache.service.IUserInfoRedisService;
import cn.wolfcode.luowowo.cache.util.RedisKeys;
import cn.wolfcode.luowowo.domain.Banner;
import cn.wolfcode.luowowo.domain.Travel;
import cn.wolfcode.luowowo.domain.User;
import cn.wolfcode.luowowo.domain.UserInfo;
import cn.wolfcode.luowowo.query.BannerQuery;
import cn.wolfcode.luowowo.repository.BannerRepository;
import cn.wolfcode.luowowo.repository.UserRepository;
import cn.wolfcode.luowowo.service.IBannerService;
import cn.wolfcode.luowowo.service.IUserInfoService;
import cn.wolfcode.luowowo.service.IUserService;
import cn.wolfcode.luowowo.util.DBHelper;
import cn.wolfcode.luowowo.util.DateUtil;
import com.sun.xml.internal.ws.resources.HttpserverMessages;
import javafx.scene.shape.Circle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class BannerServiceImpl implements IBannerService {

    @Autowired
    private BannerRepository bannerRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private MongoTemplate template;

    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IUserInfoService userInfoService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void save(Banner banner) {
        bannerRepository.save(banner);
    }

    @Override
    public void delete(String id) {
        bannerRepository.deleteById(id);
    }


    @Override
    public Banner get(String id) {
        Optional<Banner> optional = bannerRepository.findById(id);
        if(optional.isPresent()){
            return optional.get();
        }
        return null;
    }

    @Override
    public List<Banner> list() {
        return bannerRepository.findAll();
    }

    @Override
    public Page<Banner> query(BannerQuery qo) {
        //先查询出所有的地区数据，然后对它进行分页
        //1  创造出查询条件对象，然后得到分页对象，最后得到页面结果集对象
        Query query = new Query();
        //创建分页模板(包含排序规则)
        PageRequest pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
        return DBHelper.query(template,Banner.class,query,pageable);
    }


    @Override
    public void saveOrUpdate(Banner banner) {
        //如果传过来的对象有id，说明是更新操作
        //否则是保存操作  mongodb更新是全量更新，就是所有的属性都会更新
        //为了解决这个问题，必须先查询出要更新的对象  新增的时候id不为空，为空字符串，所以
        //改为判断字符串长度
        if(StringUtils.hasLength(banner.getId())){
            Banner reg = template.findById(banner.getId(), Banner.class);
            bannerRepository.save(banner);
        }else{
            //添加时为了id不为空，将它设为null
            banner.setId(null);
            bannerRepository.save(banner);
        }
    }

    @Override
    public List<Banner> queryTop5() {
        Query query = new Query();
        query.addCriteria(Criteria.where("type").is(1));
        PageRequest pr = PageRequest.of(0, 5, Sort.Direction.DESC, "_id");
        query.with(pr);
        List<Banner> banners = template.find(query, Banner.class);
        return banners;
    }
    @Override
    public List<Banner> queryTop1() {
        Query query = new Query();
        query.addCriteria(Criteria.where("type").is(2));
        PageRequest pr = PageRequest.of(0, 5, Sort.Direction.DESC, "_id");
        query.with(pr);
        List<Banner> banners = template.find(query, Banner.class);
        return banners;
    }

    //查看总访问量
    @Override
    public User getViewNum(String ownerId, HttpServletRequest request) {
        User user=userService.get(ownerId);
        String token = request.getHeader("token");
        UserInfo curUser = userInfoRedisService.getUserByToken(token);
        List<String> refIds = user.getRefIds();
        if(!curUser.getId().equals(ownerId)){
            user.setTotalView(user.getTotalView()+1);
            user.setTodayView(0);
            refIds.add(user.getId());
            user.setRefIds(refIds);
            userRepository.save(user);
        }
        return user;
    }

    //展示前八个访客
    @Override
    public List<UserInfo> queryTop8ById(String ownerId) {
        List<UserInfo> list = new ArrayList<>();
        User user = userService.get(ownerId);
        List<String> refIds = user.getRefIds();
        for (String refId : refIds) {
            UserInfo userInfo = userInfoService.findById(refId);
            list.add(userInfo);
            if(list.size()>7){
                break;
            }

        }
        return list;
    }

    //查看所有访客
    @Override
    public List<UserInfo> show(String ownerId) {
        List<UserInfo> list = new ArrayList<>();
        User user = userService.get(ownerId);
        List<String> refIds = user.getRefIds();
        for (String refId : refIds) {
            UserInfo userInfo = userInfoService.findById(refId);
            list.add(userInfo);
        }
        return list;
    }

    //今日访问量
    @Override
    public int increaseTodayview(String ownerId, HttpServletRequest request) {
        String key = RedisKeys.TODAYVIEW.join(ownerId);
        Date now = new Date();
        Date endDate = DateUtil.getEndDate(now);
        long time = DateUtil.getDateBetween(now, endDate);
        int a=0;
        String token = request.getHeader("token");
        UserInfo userInfo = userInfoRedisService.getUserByToken(token);
        if(!userInfo.getId().equals(ownerId)){
            if(redisTemplate.opsForValue().get(key)==null){
                redisTemplate.opsForValue().set(key,0,time, TimeUnit.SECONDS);
            }
            a=(int) redisTemplate.opsForValue().get(key);
            a+=1;
            redisTemplate.opsForValue().set(key,a,time, TimeUnit.SECONDS);
        }
        return a;
    }

}
